/*---------------------------------------------------------------------
 * File name: h3lis331dl.h
 *
 * Copyright (c) <2020-2022>, <ChenLong>
 *
 * All rights reserved.
 *
 * Author: ChenLong
 * Email: worldlong@foxmail.com
 *--------------------------------------------------------------------*/
#pragma once
/*
*/
#include "gpio.h"
#include "spi.h"
/*
*/
#define H3LIS331DL_WHO_AM_I_DATA      0x32
//REGISTER MAP
#define H3LIS331DL_WHO_AM_I           0x0F
#define H3LIS331DL_CTRL_REG1          0x20
#define H3LIS331DL_CTRL_REG2          0x21
#define H3LIS331DL_CTRL_REG3          0x22
#define H3LIS331DL_CTRL_REG4          0x23
#define H3LIS331DL_CTRL_REG5          0x24
#define H3LIS331DL_HP_FILTER_RESET    0x25
#define H3LIS331DL_REFERENCE          0x26
#define H3LIS331DL_STATUS_REG         0x27
#define H3LIS331DL_OUT_X_L            0x28
#define H3LIS331DL_OUT_X_H            0x29
#define H3LIS331DL_OUT_Y_L            0x2A
#define H3LIS331DL_OUT_Y_H            0x2B
#define H3LIS331DL_OUT_Z_L            0x2C
#define H3LIS331DL_OUT_Z_H            0x2D
#define H3LIS331DL_INT1_CFG           0x30
#define H3LIS331DL_INT1_SRC           0x31
#define H3LIS331DL_INT1_THS           0x32
#define H3LIS331DL_INT1_DURATION      0x33
#define H3LIS331DL_INT2_CFG           0x34
#define H3LIS331DL_INT2_SRC           0x35
#define H3LIS331DL_INT2_THS           0x36
#define H3LIS331DL_INT2_DURATION      0x37
/*
*/
class H3LIS331DL 
{
public:
  H3LIS331DL(hal::SPI *spi, hal::GPIO *cs, int ncs) :
    scale(1.0f),
    _spi(spi),
    _cs(cs),
    _ncs(ncs)
    {}
    
  float scale;
  /* After reset, must wait 1ms for soft reset to be effective, 
     before attempting any other register access. */
  void reset();
  /* Check Who am I */
  bool check();
  
  /* After config, must wait 200us for next operation */
  bool config(int accel_fs, int odr);
  bool config(uint8_t *cfg[2], int size);
  void read_accel(int16_t *accel);
  void read_data(uint8_t *data) {
    read_bytes(data, H3LIS331DL_OUT_X_L, 6);
  }
  void flush() {
    read_bytes(0, H3LIS331DL_OUT_X_L, 6);
  }
  
private:
  hal::SPI *_spi;
  hal::GPIO *_cs;
  int _ncs;
  
  void write_reg(uint8_t addr, uint8_t data);
  bool write_reg_with_check(uint8_t addr, uint8_t data);
  uint8_t read_reg(uint8_t addr);
  int read_bytes(uint8_t *data, uint8_t addr, int number);
};
